<?php


namespace App\Services;

use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use App\Exceptions\InternalException;
use App\Exceptions\InvalidRequestException;
use Illuminate\Support\Facades\Cache;

// 短信服务
class SmsService
{
    protected $configService;

    public function __construct(ConfigService $configService)
    {
        $this->configService = $configService;
    }

    /**
     *
     * @param $mobile
     * @return string
     * @throws ClientException
     */
    public function sendSms($mobile):string
    {
        // 判断手机号码在缓存中是否存在
        if (Cache::has($mobile)) {
            // 抛出客户端异常, 告诉用户请五分钟后再点击获取验证码
            throw new InvalidRequestException('请五分钟后在获取验证码');
        }

        $accessKeyId = $this->configService->get('AccessKeyID', 'aliyun');
        $accessSecret = $this->configService->get('AccessKeySecret', 'aliyun');
        $regionId = $this->configService->get('RegionId', 'sms');
        $signName = $this->configService->get('SignName', 'sms');
        $templateCode = $this->configService->get('TemplateCode', 'sms');  // 模板code
        $validTime = $this->configService->get('ValidTime', 'sms');  // 过期时间

        $code = random_int(1000, 9999);

        AlibabaCloud::accessKeyClient($accessKeyId, $accessSecret)
            ->regionId($regionId)
            ->asDefaultClient();

        try {
            $result = AlibabaCloud::rpc()
                ->product('Dysmsapi')
                // ->scheme('https') // https | http
                ->version('2017-05-25')
                ->action('SendSms')
                ->method('POST')
                ->host('dysmsapi.aliyuncs.com')
                ->options(
                    [
                        'query' => [
                            'RegionId' => $regionId,
                            'PhoneNumbers' => $mobile,
                            'SignName' => $signName,
                            'TemplateCode' => $templateCode,
                            'TemplateParam' => "{code: {$code}}",
                        ],
                    ]
                )
                ->request();
            $result = $result->toArray();
        } catch (ClientException $e) {
            // 内部异常处理
            throw new InternalException("sms客户端异常");
        } catch (ServerException $e) {
            // 内部异常处理
            throw new InternalException("sms服务器异常");
        }



        if ($result['Message'] != "OK") {
            // 发送短信失败, 同时记录到日志中
            throw new InternalException('短信发送失败');
        }

        // 以手机号码为key, 以为验证码为value, 保存到缓存中, 缓存时间为5分钟
        Cache::put($mobile, $code, now()->addMinutes($validTime));

        return $code;
    }

    /**
     * 验证手机号和验证码是否匹配
     * @param $mobile
     * @param $yzm
     * @return bool
     */
    public function verify($mobile, $yzm):bool
    {
        return Cache::get($mobile) == $yzm;
    }
}